import { Observable, Subject } from 'rxjs';

import { OpenPluginController } from '../controller/open-plugin-controller';
import { PluginConfig } from '../interface/plugin-config';

export class OpenPluginService {
    /**
     * 唯一实例
     *
     * @private
     * @static
     * @memberof OpenPluginService
     */
    private static readonly instance = new OpenPluginService();

    /**
     * plugin实例map表
     *
     * @type {Map<string, OpenPluginController>}
     * @memberof OpenPluginService
     */
    readonly pluginInstanceMap: Map<string, OpenPluginController> = new Map();

    /**
     * 打开节点实例变更
     *
     * @private
     * @type {Subject<void>}
     * @memberof OpenPluginService
     */
    private readonly subject: Subject<void> = new Subject();

    /**
     * Creates an instance of OpenPluginService.
     * @memberof OpenPluginService
     */
    private constructor() {}

    /**
     * 打开插件
     *
     * @param {PluginConfig} config
     * @return {*}  {Promise<OpenPluginController>}
     * @memberof OpenPluginService
     */
    async open(config: PluginConfig): Promise<OpenPluginController> {
        const tag = config.tag;
        if (config.isCache == null) {
            config.isCache = true;
        }
        let item = this.pluginInstanceMap.get(tag);
        if (item) {
            item.show();
        } else {
            item = new OpenPluginController(config);
            item.wrapper.addEventListener('closeWrapper', () => {
                this.pluginInstanceMap.delete(tag);
                this.subject.next();
            });
            this.pluginInstanceMap.set(tag, item);
        }
        this.subject.next();
        return item;
    }

    /**
     * 订阅打开插件实例变更事件
     *
     * @return {*}  {Observable<void>}
     * @memberof OpenPluginService
     */
    subInstanceChange(): Observable<void> {
        return this.subject.asObservable();
    }

    /**
     * 获取实例
     *
     * @static
     * @return {*}  {OpenPluginService}
     * @memberof OpenPluginService
     */
    static getInstance(): OpenPluginService {
        return this.instance;
    }
}
